<?php
/*
 * @Date: 2020-05-03 22:03:52
 * @名称: 数据优化
 * @版本: 0.01
 * @作者: 初雪桜
 * @邮箱: 202184199@qq.com
 * @最后编辑人: 初雪桜
 * @LastEditTime: 2020-08-08 17:36:17
 * @FilePath: /服务器/app/useradmin/controller/DataOptimization.php
 */

namespace app\useradmin\controller;

use app\BaseController;
use think\facade\Db;
use think\facade\View;


class DataOptimization extends BaseController
{
    public function index() //数据优化
    {
        $imageTableList  = Db::table('book_info_project_info_controller')
            ->where([
                "there_are_no_local_files" => 0,
            ])
            ->select();
        return view('DataOptimization/index', [
            "useradmin" => config("useradminConfig.useradmin_serverHost"),
            "imageTableList" => $imageTableList,
        ]);
    }
    public function runTaks()
    {
        set_time_limit(0);
        $uploaded_files = input('post.uploaded_files'); //寻找重复文件
        $database_redundant_data = input('post.database_redundant_data'); //删除多余数据 如 删除漫画后的残留

        if ($uploaded_files) {
            FindDuplicateFiles();
        }
        if ($$database_redundant_data) {
            // FileManagementController();
        }
    }

    function DeletedCategorie() //删除分类数据
    {
        set_time_limit(0); //设置用不超时
        $classified_catalogue = [];
        $deleteTableList = []; //更新次数
        $updateNumber = 0; //更新次数
        $updateSuccessNumber = 0; //更新语句成功次数
        $classified_catalogue_list = Db::table('classified_catalogue')
            ->where(['state' => 0])
            ->field(['_id', "title", 'is_web'])
            ->select();
        foreach ($classified_catalogue_list as $key => $value) {
            $isTable = Db::query("SHOW TABLES LIKE 'book_info_categories_info_$value[_id]'");
            if ($isTable) {
                $book_info_list = Db::table("book_info_categories_info_$value[_id]") //查询当前分类下所有的表
                    ->alias('book_info_categories')
                    ->join('book_info book_info', 'book_info_categories.book_id = book_info._id')
                    ->field(["book_info.*"])
                    ->select();

                foreach ($book_info_list as $key => $Avalue) { //循环项目列表
                    $classified_catalogue = explode(',', $Avalue['categories']);
                    $new_classified_catalogue = '';
                    foreach ($classified_catalogue as $key => $Bvalue) { //循环自己的分类
                        if ($Bvalue != $value['title']) { //判断当前循环的分类有没有本分类
                            $new_classified_catalogue .= ",$Bvalue"; //要时不时的话就加上,+分类名
                        }
                    }
                    $new_classified_catalogue = substr($new_classified_catalogue, 1); //删除第一个字符
                    $updateNumber++; //运行语句++
                    $state = Db::table('book_info')
                        ->where($Avalue)
                        ->update(['categories' => $new_classified_catalogue]);
                    if ($state) {
                        $updateSuccessNumber++; //成功++
                    }
                }
                //这里应该在 上面的foreach里面 但是 太占用响应了
                $sql =  "truncate TABLE book_info_categories_info_$value[_id]";
                $deleteTable = Db::query($sql);
                if ($deleteTable) {
                    $deleteTableList[] =  $value['title'];
                }
            } else {
            }
        }
        $returnData = [
            "deleteTableList" => $deleteTableList, //被删除的表的名字 如 ['百合','基佬']
            "updateNumber" => $updateNumber, //执行的语句次数
            "updateSuccessNumber" => $updateSuccessNumber, //执行成功的次数
            "errorUpdateNumber" => $updateNumber - $updateSuccessNumber, //执行失败次数
        ];
        return successJsonReturn($returnData);
    }

    public function FileManagementController()
    {
        $allShow = input("allShow", "0"); // 0只显示异常 1全部显示 2只显示丢失 3 只显示多余
        $tableName = input("get.tableName", "dawdwadwa6d46aw"); // 0只显示异常 1全部显示 2只显示丢失 3 只显示多余
        $GLOBALS['DataDoesNotExist'] = []; //遍地本地文件 所寻找的漫画或漫画分卷 在数据库中不存在
        $fileMissing = []; //文件丢失 数据库中有这个文件 但是本地却没有

        if ($tableName == "all") {
            $ImageTable = Db::table('book_info_project_info_controller') //查询所有的图片表
                ->where([
                    "there_are_no_local_files" => 0,
                ])
                ->select();
        } else {
            $ImageTable = Db::table('book_info_project_info_controller') //查询所有的图片表
                ->where([
                    "there_are_no_local_files" => 0,
                    "table_name" => $tableName,
                ])
                ->order("id desc")
                ->select();
            if (!$ImageTable) {
                return view("OtherPage/Error", [
                    "errorCode" => "FileManagementController-00001",
                    "errorTitle" => "所选择的表不存在",
                    "errorMsg" => "请选择正确表",
                ]);
                // return errorJsonReturn("deleteRedundantDocuments-10008");
            }
        }
        $ImageTableList = []; //查询所有的图片数据 //!json格式 书籍名 =》 分卷名 =》图片名=》图片信息
        $TheFileIsNormal = []; //文件正常 //!json格式 书籍名 =》 分卷名 =》图片名=》图片信息
        foreach ($ImageTable as $key => $value) {
            $tableName = $value["table_name"];
            $imageFileList[$tableName] = myScanDir("public/update/BookImages/$tableName", true); //返回服务区全部文件 //!当全部执行完成 会删除数据库中已存在数据 如果剩下就是多余的 可能是其他为检索表的数据
            $ImageTableList[$value["table_name"]] = Db::table($value["table_name"])
                ->where([
                    "is_local_file" => 1,
                ])
                ->select();
            //查询所有图片
            //判断列表是否为空
            if (!count($ImageTableList[$value["table_name"]])) {
                unset($ImageTableList[$value["table_name"]]);
            } else {
                foreach ($ImageTableList[$value["table_name"]] as $key => $sonValue) {
                    $fileName = $sonValue['save_file_name']; //保存文件名
                    $extension = $sonValue['extension']; //扩展名
                    $userId = $sonValue['user_id']; //用户id
                    $projectId = $sonValue["project_id"]; //分卷id
                    $bookId = $sonValue["_id"]; //书籍id
                    if (isset($imageFileList[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"])) { //判断数据库中的数据 在本地是否有这个文件
                        $TheFileIsNormal[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"] = $imageFileList[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"];
                        unset($imageFileList[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"]);
                    } else {
                        $fileMissing[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"] = ["msg" => "文件丢失"];
                        unset($imageFileList[$tableName][$bookId][$projectId][$userId]["$fileName.$extension"]);
                    }
                }
            }
        }

        // dump($imageFileList); //!多余文件
        // dump($fileMissing); //!文件不存在
        // dump($TheFileIsNormal); //!正常
        switch ($allShow) {
            case "2": //# 只显示丢失
                $TheFileIsNormal  = []; //*正常
                $imageFileList = []; //*文件多余
                $state = "只显示丢失";
                break;
            case "3": //# 只显示多余
                $TheFileIsNormal  = []; //*正常
                $fileMissing = []; //丢失
                $state = "只显示多余";
                break;
            case "1": //# 显示全部
                $state = "显示全部";
                break;
            default:
                $TheFileIsNormal  = []; //*正常
                $state = "只显示异常";
                break;
        }
        return view('DataOptimization/FileManagementController/index', [
            "url" => 'http://' . $_SERVER['HTTP_HOST'] . "/",
            "state" => $state,
            "TheFileIsNormal" => $TheFileIsNormal, //!正常
            "imageFileList" => $imageFileList, //!多余文件
            "fileMissing" => $fileMissing, //!文件不存在
        ]);
    }
    /**
     * 删除多余文件
     */
    public function deleteRedundantDocuments()
    {
        # 删除多余文件
        $imageSrc = input('imageSrc');
        $imageSrc = explode("public/update/BookImages/", $imageSrc);
        if (count($imageSrc) != 2) { //删除文件 要先吧开头的 puablic/update/BookImages/ 匹配掉 如果匹配不到提示
            return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
        } else {
            $srcInfo = explode("/", $imageSrc[1]);
            if (count($srcInfo) != 5) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
            }
            $tableName = $srcInfo[0];
            $bookId = $srcInfo[1];
            $projectId = $srcInfo[2];
            $userId = $srcInfo[3];
            $fileInfo = explode(".", $srcInfo[4]);


            if (count($fileInfo) != 2) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
            }
            $fileName = $fileInfo[0];
            $fileExtension = $fileInfo[1];
            try {
                $imageInfo =  Db::table($tableName)
                    ->where([
                        "_id" => $bookId,
                        "project_id" => $projectId,
                        "user_id" => $userId,
                        "save_file_name" => $fileName,
                        "extension" =>  $fileExtension,
                    ])
                    ->find();

                if ($imageInfo) {
                    return json_decode(errorJsonReturn("deleteRedundantDocuments-10002")->getContent(), true);
                }
            } catch (\Throwable $th) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-Database-10001")->getContent(), true);
            }
            if (!in_array($fileExtension, array("jpg", "jpeg", "png", "gif"))) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10003")->getContent(), true);
            }
            if (is_file(input('imageSrc'))) {
                if (unlink(input('imageSrc'))) {
                    return json_decode(successJsonReturn()->getContent(), true);
                } else {
                    return json_decode(errorJsonReturn("deleteRedundantDocuments-10004")->getContent(), true);
                }
            } else {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10005")->getContent(), true);
            }
        }
    }
    //删除文件丢失
    public function DeleteMissingFiles()
    {
        $imageSrc = input('imageSrc');
        $imageSrc = explode("public/update/BookImages/", $imageSrc);
        if (count($imageSrc) != 2) { //删除文件 要先吧开头的 puablic/update/BookImages/ 匹配掉 如果匹配不到提示
            return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
        } else {
            $srcInfo = explode("/", $imageSrc[1]);
            if (count($srcInfo) != 5) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
            }
            $tableName = $srcInfo[0];
            $bookId = $srcInfo[1];
            $projectId = $srcInfo[2];
            $userId = $srcInfo[3];
            $fileInfo = explode(".", $srcInfo[4]);
            if (count($fileInfo) != 2) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10001")->getContent(), true);
            }
            $fileName = $fileInfo[0];
            $fileExtension = $fileInfo[1];
            try {
                $imageInfo =  Db::table($tableName)
                    ->where([
                        "_id" => $bookId,
                        "project_id" => $projectId,
                        "user_id" => $userId,
                        "save_file_name" => $fileName,
                        "extension" => "." . $fileExtension,
                    ])
                    ->find();
                if (!$imageInfo) {
                    return json_decode(errorJsonReturn("deleteRedundantDocuments-10006")->getContent(), true);
                }
            } catch (\Throwable $th) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-Database-10001")->getContent(), true);
            }
            switch ($fileExtension) {
                case 'jpeg':
                    break;
                case 'png':
                    break;
                case 'gif':
                    break;
                default:
                    return json_decode(errorJsonReturn("deleteRedundantDocuments-10003")->getContent(), true);
                    break;
            }
            if (is_file(input('imageSrc'))) {
                return json_decode(errorJsonReturn("deleteRedundantDocuments-10007")->getContent(), true);
            } else {
                Db::table($tableName)
                    ->where([
                        "_id" => $bookId,
                        "project_id" => $projectId,
                        "user_id" => $userId,
                        "save_file_name" => $fileName,
                        "extension" => "." . $fileExtension,
                    ])
                    ->delete();
            }
            return json_decode(successJsonReturn()->getContent(), true);
        }
    }
}

function myScanDir($dir, $imagesComplete = false) //遍历目录
{
    $file_arr = scandir($dir);
    $new_arr = [];
    foreach ($file_arr as $item) {
        if ($item != ".." && $item != "." && $item != ".DS_Store") {
            if (is_dir($dir . "/" . $item)) {
                $new_arr[$item] = myScanDir($dir . "/" . $item, $imagesComplete);
            } else {
                //图片完整检测 检测是不是为图片
                if ($imagesComplete) {
                    if (@imagecreatefromgif($dir . "/" . $item)) {
                        $new_arr[$item] = [
                            "fileUpdateTime" => date("Y-m-d H:i:s", filectime($dir . "/" . $item)), //!获取文件修改时间
                            "fileReadTime" => date("Y-m-d H:i:s", fileatime($dir . "/" . $item)), //!获取文件最后被访问时间
                            "fileSrc" => ($dir . "/" . $item), //!文件路径
                            "fileSize" => getSize(filesize($dir . "/" . $item)), //!文件大小
                            "extends" => true,
                        ];
                    } else {
                        $new_arr[$item] = [
                            "fileUpdateTime" => date("Y-m-d H:i:s", filectime($dir . "/" . $item)), //!获取文件修改时间
                            "fileReadTime" => date("Y-m-d H:i:s", fileatime($dir . "/" . $item)), //!获取文件最后被访问时间
                            "fileSrc" => ($dir . "/" . $item), //!文件路径
                            "fileSize" => getSize(filesize($dir . "/" . $item)), //!文件大小
                            "extends" => false,
                        ];
                    }
                } else {
                    $new_arr[$item] = [
                        "fileUpdateTime" => date("Y-m-d H:i:s", filectime($dir . "/" . $item)), //!获取文件修改时间
                        "fileReadTime" => date("Y-m-d H:i:s", fileatime($dir . "/" . $item)), //!获取文件最后被访问时间
                        "fileSrc" => ($dir . "/" . $item), //!文件路径
                        "fileSize" => getSize(filesize($dir . "/" . $item)), //!文件大小
                        "extends" => true,
                    ];
                }
            }
        }
    }
    return $new_arr;
}

function FindDuplicateFiles($dir = 'public/update') //寻找重复文件
{
    set_time_limit(0);
    bianli1($dir);
    $delete = [];
    $updateNumber = 0;
    $fileSize = 0;
    foreach ($GLOBALS['fileList'] as $key => $value) {
        if (!isset($value['repeat'])) {
            unset($GLOBALS['fileList'][$key]);
        } else {
            foreach ($value['repeat'] as $key => $reoeatValue) {
                $state = Db::table('book_info_images_list')
                    ->where(['images_src' => $reoeatValue])->update([
                        "repeat" => 1,
                        "images_src" => $value["fileSrc"],
                    ]);
                if ($state) {
                    $updateNumber++;
                }
                $fileSize += filesize($reoeatValue);
                if (unlink($reoeatValue)) {
                    $delete[] = $reoeatValue;
                };
            }
        }
    }
    $returnData = [
        "repeat" => count($delete), //删除的数据总数
        "repearData" => $delete, //删除的数据
        "allFileSize" => getSize($fileSize), //总删除的数据大小
        "updateMysql" => $updateNumber, //更新的数据库
    ];
    return successJsonReturn($returnData);
}
function getSize($filesize)
{
    if ($filesize >= 1073741824) {

        $filesize = round($filesize / 1073741824 * 100) / 100 . ' GB';
    } elseif ($filesize >= 1048576) {

        $filesize = round($filesize / 1048576 * 100) / 100 . ' MB';
    } elseif ($filesize >= 1024) {

        $filesize = round($filesize / 1024 * 100) / 100 . ' KB';
    } else {

        $filesize = $filesize . ' 字节';
    }

    return $filesize;
}
function bianli1($dir)
{
    $files = array();
    if ($head = opendir($dir)) {
        while (($file = readdir($head)) !== false) {
            if ($file != ".." && $file != ".") {
                if (is_dir($dir . '/' . $file)) {
                    $files[$file] = bianli1($dir . '/' . $file);
                } else {
                    if ($file != ".DS_Store") {
                        // $files[] = [md5_file($dir . '/' . $file) => $file];
                        $file_md5 = md5_file($dir . '/' . $file);
                        if (isset($GLOBALS["fileList"][$file_md5])) {
                            //发现重复的
                            if (!isset($GLOBALS["fileList"][$file_md5]['base64'])) { //判断我重复的这条记录有没有获取base64
                                $openFile = fopen($GLOBALS["fileList"][$file_md5]['fileSrc'], "rb");
                                $GLOBALS["fileList"][$file_md5]['base64'] = base64_encode(fread($openFile, filesize($dir . '/' . $file))); //没有打开我打开并且添加到数组
                            }
                            $openFile = fopen($dir . '/' . $file, "rb");
                            $fileBase64 = base64_encode(fread($openFile, filesize($dir . '/' . $file))); //没有打开我打开并且添加到数组
                            if ($fileBase64 == $GLOBALS["fileList"][$file_md5]['base64']) {
                                $GLOBALS["fileList"][$file_md5]['repeat'][] = $dir . '/' . $file;
                            }
                        } else {
                            $openFile = fopen($dir . '/' . $file, "rb");
                            $GLOBALS["fileList"][$file_md5] = [
                                "fileName" => $file,
                                "fileSrc" => $dir . '/' . $file,
                                // "base64" => base64_encode(fread($openFile, filesize($dir . '/' . $file))),
                            ]; //把我遍历到的数据存到一个数组
                        }
                    }
                }
            }
        }
    }
    closedir($head);
    return $files;
}
